/**
 * 
 */
package com.appspot.android2gather.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.android2gather.spikes.TestServlet;
import com.google.gson.Gson;

/**
 * @author Stefan Thaler
 */
public class FrontController
    extends HttpServlet
{
    /**
     * 
     */
    private static final long serialVersionUID = -4697330614229326368L;

    private static final Logger log = Logger.getLogger( FrontController.class.getName() );

    private static Gson gson = new Gson();

    private HttpServlet getDelegate( String pathInfo )
    {

        StringTokenizer pathTokens = new StringTokenizer( pathInfo, "/" );
        String path = "";
        if ( pathTokens.hasMoreTokens() )
        {
            path = pathTokens.nextToken();
            if ( path.equals( "activity" ) )
            {
                log.info( "delegating " + pathInfo + " to: " + ActivityManager.class.getName() );
                return new ActivityManager();
            }

            if ( path.equals( "attend" ) )
            {
                log.info( "delegating " + pathInfo + " to: " + AttendanceManager.class.getName() );
                return new AttendanceManager();
            }

            if ( path.equals( "search" ) )
            {
                log.info( "delegating " + pathInfo + " to: " + ActivitySearch.class.getName() );
                return new ActivitySearch();
            }

            if ( path.equals( "logon" ) )
            {
                log.info( "delegating " + pathInfo + " to: " + LogonManager.class.getName() );
                return new LogonManager();
            }

            if ( path.equals( "test" ) )
            {
                log.info( "delegating " + pathInfo + " to: " + TestServlet.class.getName() );
                return new TestServlet();
            }

        }

        return new NullServlet();
    }

    private boolean processAuthentication( HttpServletRequest req, HttpServletResponse resp )
        throws IOException
    {
        if ( req.getUserPrincipal() != null )
        {
            return true;
        }
        else
        {
            resp.getWriter().println( gson.toJson( new com.appspot.android2gather.activity.ErrorMessage( "Not authenticated." ) ) );
            return false;
        }
    }

    @Override
    protected void service( HttpServletRequest req, HttpServletResponse resp )
        throws ServletException, IOException
    {
        // logging
        log.info( "serving" );
        // authentication
        HttpServlet requestDelegate = getDelegate( req.getPathInfo() );
        
        if ( requestDelegate.getClass().equals( LogonManager.class ) || processAuthentication( req, resp ) )
        { 
            try
            {
                requestDelegate.service( req, resp );
                
            }
            catch ( Exception e )
            {
                log.warning(getStrackTrace(e));
                resp.getWriter().write( gson.toJson( new com.appspot.android2gather.activity.ErrorMessage("Oooops. Something went wrong:"+e.getMessage()) ) );
            }

        } 
        else
        {
            return;
        }
        // logging
        log.info( "serving finished" );
    }
    
    /**
     * Converts a <code>Stacktrace</code> to a <code>String</code>. TODO refactor
     * 
     * @param t
     * @return the Stacktrace as a <code>String</code>
     */
    public static String getStrackTrace( Throwable t )
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter( sw, true );
        t.printStackTrace( pw );
        pw.flush();
        sw.flush();
        return sw.toString();
    }
    
    
}
